package jude.java.money.provide;


/**
 * 可后退的provider, 某些对象重新提供
 */
public abstract class BackablePagingProvider<T> extends PagingProvider<T> {
	
	private Object[] memory;
	private int memoryPoint;	//下一个空白
	private int count;			//最多可后退数
	private int left;			//当前后退剩余数
	
	protected BackablePagingProvider() {
		this(50, false);
	}
	
	protected BackablePagingProvider(int pageSize) {
		this(pageSize, false);
	}
	
	protected BackablePagingProvider(int pageSize, boolean reverse) {
		super(pageSize, reverse);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public synchronized T get() {
		if (memory != null) {
			if (left > 0) {
				left --;
				count ++;
				int n = memoryPoint;
				memoryPoint = (memoryPoint + 1) % memory.length;
				return (T)memory[n];
			} else {
//				left = Math.min(left + 1, memory.length);
				count = Math.min(count + 1, memory.length);
				int n = memoryPoint;
				memoryPoint = (memoryPoint + 1) % memory.length;
				T o = super.get();
				memory[n] = o;
				return o;
			}
		}
		return super.get();
	}
	
	public void back(int c) {
		if (memory == null || c > count - left)
			throw new RuntimeException();
		memoryPoint = (memoryPoint + memory.length - c) % memory.length;
		count -= c;
		left += c;
	}
	
	public void back() {
		back(1);
	}
	
	public void setHisrotySize(int size) {
		if (memory != null && memory.length == size)
			return;
		if (size <= 0) {
			memory = null;
		} else {
			memory = new Object[size];
			memoryPoint = 0;
			count = 0;
			left = 0;
		}
	}
	
	@Override
	public synchronized void reset() {
		super.reset();
		memoryPoint = 0;
		count = 0;
		left = 0;
	}
	
}
